#ifndef OGLAPP
#define OGLAPP

#include <iostream>
#include <vector>
#include <string>

#include <base\vec2i.h>
#include <utils\timer.h>
#include <render\camera.h>
#include <render\avatar.h>
#include <render\threads\viewResolver.h>
#include <app\states\viewingParametersState.h>
#include <network\streamingClient.h>

#include <base\matrix.h>
#include <base\viewvolume.h>

#include <openglut.h>

#define WINDOW_WIDTH    768
#define WINDOW_HEIGHT   768
#define WINDOW_LEFT      0
#define WINDOW_TOP       0
#define WINDOW_TITLE    "Streaming of distributed virtual environment via movement prediction."

using namespace std;

class viewResolver;

class oglapp {

  static oglapp *_instance;        ///< instance of the application

  double elapsed_time;
  timer render_time;               ///< evaluate time between two calls of the onIdle callback

  camera mycamera;                 ///< camera
  avatar myavatar;                 ///< current location(x, y, z) and rotation

  viewingParametersState *vpstate;
  viewResolver *view_resolver;     ///< prepare scene and render it

  vec2i window_size;

  int frame_time, time, timebase, fps, frames;  ///< performance and movement speed

private:

  oglapp();
  oglapp(const oglapp &);
  oglapp *operator=(const oglapp &);
  ~oglapp();

protected:

  vec2i old_mouse_pos;

  bool initializeOGLApplication();

  static void onDisplay(void);
  static void onResize(int w, int h);
  static void onKeyPress(unsigned char key, int x, int y);
  static void onKeyDown(int key, int x, int y);
  static void onKeyUp(int key, int x, int y);
  static void onMouseButton(int button, int state, int x, int y);
  static void onMousePassiveMotion(int x, int y);
  static void onMouseWheel(int wheel, int direction, int x, int y);
  static void onIdle();

private:

  void drawTargetCross();
  void resolveFPS();  
  void renderBitmapString(float x, float y, string str);

public:

  static oglapp &instance();

  // start the application
  bool start(int argc, char **argv);
  
};

#endif